package be.ac.ulb.mlg.utils;

/*
 * The MIT License (MIT)
 * 
 * Copyright (c) 2013 Jean-Sebastien Lerat (Jean-Sebastien.Lerat@ulb.ac.be)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

/**
 * 
 * @author Jean-Sebastien Lerat (Jean-Sebastien.Lerat@ulb.ac.be)
 * @version 1.00, 24/06/2013
 */

import java.util.Arrays;

public final class TestUtils {
	public static enum DataSize{
		SMALL(6,2),
		MEDIUM(300,10),
		LARGE(160000,1000);
		public final int rows,columns;
		private DataSize(int rows, int columns){
			this.rows		= rows;
			this.columns	= columns;
		}
	}
	
	public static final double DEFAULT_P_MISSING= 0.01;
	public static final double DEFAULT_EPSILON	= 1e-10;
	public static final double DEFAULT_P_IGNORE	= 0.001;
	public static final boolean IGNORE			= false;
	
	public static double[][] generateData(DataSize size,final double scale){
		return generateData(size,scale,DEFAULT_P_MISSING);
	}
	public static double[][] generateData(DataSize size,final double scale,final double pMissing){
		final double[][] res = new double[size.rows][size.columns];
		for(double[] sub:res)
			for(int i=0;i<size.columns;i++)
				sub[i] = Math.random()>pMissing?Math.random()*scale:Double.NaN;
		return res;
	}
	public static boolean equals(double[][] a,double[][] b) {
		return equals(DEFAULT_EPSILON, a, b);
	}
	public static double[][] copy(double[][] init) {
		final double[][] cpy = new double[init.length][];
		for(int i=0;i<cpy.length;i++)
			cpy[i] = Arrays.copyOf(init[i],init[i].length);
		return cpy;
	}
	public static boolean[][] copy(boolean[][] init) {
		final boolean[][] cpy = new boolean[init.length][];
		for(int i=0;i<cpy.length;i++)
			cpy[i] = Arrays.copyOf(init[i],init[i].length);
		return cpy;
	}
	public static boolean equals(final double EPS,double a,double b) {
		return Math.abs(a - b) < EPS;
	}
	public static boolean equals(double a,double b) {
		return equals(DEFAULT_EPSILON,a,b);
	}
	public static boolean equals(final double EPS,double[][] a,double[][] b) {
		if(a == null || b == null )return false;
		if(a.length != b.length)return false;
		for(int i=0;i<a.length;i++){
			if(a[i] == null || b[i] == null )return false;
			if(a[i].length != b[i].length)return false;
			for(int j=0;j<a[i].length;j++)
				if(Math.abs(a[i][j] - b[i][j]) > EPS) return false;
		}
		return true;
	}
	public static boolean[][] generateIgnore(DataSize size){
		return generateIgnore(size, DEFAULT_P_IGNORE);
	}
	public static boolean[][] generateIgnore(DataSize size,final double pIgnore){
		boolean atLeastOne = false;
		final boolean[][] res = new boolean[size.rows][size.rows];
		for(boolean[] sub:res)
			for(int i=0;i<sub.length;i++)
				if(Math.random()>pIgnore){
					sub[i] = !IGNORE;
				}else{
					sub[i] = IGNORE;
					atLeastOne = true;
				}
		if(!atLeastOne) res[0][1]=res[1][0]=IGNORE;
		return res;
	}
}
